﻿/**
 * @file		dd_pmc_tmr32.c
 * @brief		PMC 32 bit reload timer driver
 * @note		None
 * @attention	None
 * 
 * <B><I>Copyright 2016 Socionext Inc.</I></B>
 */

#include "dd_pmc_tmr32.h"
#include "dd_pmc_crg.h"
#include "dd_arm.h"
#include "pmc.h"

/*----------------------------------------------------------------------*/
/* Definition															*/
/*----------------------------------------------------------------------*/
//---------------------------- driver section ----------------------------
// Nothing Special
#ifdef CO_DDIM_UTILITY_USE
//---------------------------- utility section ---------------------------
// Nothing Special
//---------------------------- colabo section ----------------------------
// Nothing Special
#endif

/*----------------------------------------------------------------------*/
/* Enumeration															*/
/*----------------------------------------------------------------------*/
//---------------------------- driver section ----------------------------
// Nothing Special

#ifdef CO_DDIM_UTILITY_USE
//---------------------------- utility section ---------------------------
// Nothing Special
//---------------------------- colabo section ----------------------------
// Nothing Special
#endif

/*----------------------------------------------------------------------*/
/* Structure															*/
/*----------------------------------------------------------------------*/
//---------------------------- driver section ----------------------------
// Nothing Special

#ifdef CO_DDIM_UTILITY_USE
//---------------------------- utility section ---------------------------
// Nothing Special
//---------------------------- colabo section ----------------------------
// Nothing Special
#endif

/*----------------------------------------------------------------------*/
/* Global Data															*/
/*----------------------------------------------------------------------*/
//---------------------------- driver section ----------------------------
// Soft-Counter : 1 - 0xFFFFFFFF
static volatile ULONG		gDD_PMC_TMR32_Soft_Counter		= 0;

// Initial value of Soft-Counter : 1 - 0xFFFFFFFF
static volatile ULONG		gDD_PMC_TMR32_Soft_Counter_Ini	= 0;

// Reload Flag : Reload = 1 / One-Shot = 0
static volatile UCHAR		gDD_PMC_TMR32_Set_Reload_Flg	= 0;

// Pointer of Callback Function
static volatile VP_CALLBACK	gDD_PMC_TMR32_Callback			= NULL;

// OUT Level
static volatile UINT32		gDD_PMC_TMR32_Out_Level			= 0;

#ifdef CO_DDIM_UTILITY_USE
//---------------------------- utility section ---------------------------
// Nothing Special
//---------------------------- colabo section ----------------------------
// Nothing Special
#endif

/*----------------------------------------------------------------------*/
/* Macro																*/
/*----------------------------------------------------------------------*/
//---------------------------- driver section ----------------------------
// Nothing Special
#ifdef CO_DDIM_UTILITY_USE
//---------------------------- utility section ---------------------------
// Nothing Special
//---------------------------- colabo section ----------------------------
// Nothing Special
#endif

/*----------------------------------------------------------------------*/
/* Local Function														*/
/*----------------------------------------------------------------------*/
//---------------------------- driver section ----------------------------
static UCHAR dd_pmc_tmr32_cal_digit( ULONG value );
static INT32 dd_pmc_tmr32_check_overflow( ULONG param_1, ULONG param_2 );
static INT32 dd_pmc_tmr32_get_soft_counter( ULONG clk, ULONG time, ULONG dividing, ULONG* soft_counter );

#ifdef CO_DDIM_UTILITY_USE
//---------------------------- utility section ---------------------------
// Nothing Special
//---------------------------- colabo section ----------------------------
// Nothing Special
#endif

/*----------------------------------------------------------------------*/
/* Grobal Function														*/
/*----------------------------------------------------------------------*/
//---------------------------- driver section ----------------------------
/**
 * @brief  The operation condition of Reload Timer is set.
 * @param  T_DD_PMC_TMR32_CTRL* tmr32_ctrl
 * @return INT32 D_DDIM_OK/D_DD_PMC_TMR32_INPUT_PARAM_ERR
 */
INT32 Dd_PMC_TMR32_Ctrl( T_DD_PMC_TMR32_CTRL const* const tmr32_ctrl )
{
#ifdef CO_PARAM_CHECK
	if( tmr32_ctrl == NULL ){
		Ddim_Assertion(("Dd_Timer32_Ctrl: input param error. [*tmr32_ctrl] NULL\n"));
		return D_DD_PMC_TMR32_INPUT_PARAM_ERR;
	}
#endif

	// It sets it to the register
	IO_PMC.TMR.TMCSR.word		= tmr32_ctrl->csr.word; //set TMCSR
	IO_PMC.TMR.TMCSR.word	   &= 0xFFFFFFF8; //CLR TMCSR-UF/CNTE/TRG
	IO_PMC.TMR.TMRLR0			= tmr32_ctrl->rlr1;
	IO_PMC.TMR.TMRLR1			= tmr32_ctrl->rlr2;

	// The reload counter is set
	gDD_PMC_TMR32_Soft_Counter		= tmr32_ctrl->soft_counter;
	gDD_PMC_TMR32_Soft_Counter_Ini	= tmr32_ctrl->soft_counter;

	// Reload check
	if( tmr32_ctrl->csr.bit.reld == 1 ){
		gDD_PMC_TMR32_Set_Reload_Flg = 1;	// Reload
	}
	else{
		gDD_PMC_TMR32_Set_Reload_Flg = 0;	// One shot
	}

	// The callback function is registered
	gDD_PMC_TMR32_Callback = tmr32_ctrl->pcallback;

	return D_DDIM_OK;
}

/**
 * @brief  Hard Counter, Soft Counter, and other parameters are calculated according
           to the designated time (usec).
           If it doesn't calculate, Input Parameter Error is returned.
 * @param  ULONG usec, T_DD_PMC_TMR32_CTRL* tmr32_ctrl, ULONG soft_counter
 * @return INT32 D_DDIM_OK/D_DD_PMC_TMR32_INPUT_PARAM_ERR
 */
INT32 Dd_PMC_TMR32_Calculate( ULONG usec, T_DD_PMC_TMR32_CTRL* const tmr32_ctrl )
{
	ULONG  total_count;
	ULONG  dividing[3];
	ULONG  count_base, count_base_wk;
	ULONG  peri_clk, peri_clk_wk;
	ULONG  soft_counter = 1;
	ULONG  soft_cnt;
	ULONG  dividing_wk_1, dividing_wk_2, dividing_wk_3;
	ULONG  peri_cnt_1 = 0;
	ULONG  peri_cnt_2 = 0;
	ULONG  peri_cnt_3 = 0;
	ULONG  margin_1, margin_2, margin_3;
	INT32  ret;
	INT8   div_wk;
	UCHAR  find_flag = 0;

	dividing[0]	 = 2;
	dividing[1]	 = 8;
	dividing[2]	 = 32;

#ifdef CO_PARAM_CHECK
	if( usec == 0 ){
		Ddim_Assertion(("Dd_PMC_TMR32_Calculate: input param error. [usec] = 0\n"));
		return D_DD_PMC_TMR32_INPUT_PARAM_ERR;
	}
	if( tmr32_ctrl == NULL ){
		Ddim_Assertion(("Dd_PMC_TMR32_Calculate: input param error. [*tmr32_ctrl] NULL\n"));
		return D_DD_PMC_TMR32_INPUT_PARAM_ERR;
	}
#endif

	if ( Dd_PMC_CRG11_Get_CRPLC_PLLBYPASS()){
		// 32KHz.
		peri_clk = 32000 / (Dd_PMC_CRG11_Get_CRDM4_DIVMODE() + 1);
	}
	else {
		// 100MHz.
		peri_clk = 100000000 / (Dd_PMC_CRG11_Get_CRDM4_DIVMODE() + 1);
	}

	count_base = peri_clk * usec;	// Number of total counts(Overflow is a disregarded number of counts)

	peri_clk_wk = peri_clk;
	count_base_wk = count_base;

	for( div_wk = 2; div_wk >= 0; div_wk-- ){
		count_base = (peri_clk / 1000000) * usec;
		if( (count_base / dividing[div_wk]) < 1 ){
			continue;
		}
		if( (count_base % dividing[div_wk]) != 0 ){
			continue;
		}
		for( ;; ){
			if( (count_base_wk & (dividing[div_wk] - 1)) == 0 ){
				soft_cnt = soft_counter;

				// Check overflow
				ret = dd_pmc_tmr32_get_soft_counter( peri_clk_wk, usec, dividing[div_wk], &soft_counter );
				if( ret == 0 ){
					if( soft_cnt == soft_counter ){
						find_flag = 1;
						break;
					}
					peri_clk_wk = peri_clk / soft_counter;
					count_base_wk = peri_clk_wk * usec;
				}
				else{
					break;
				}
			}
			else{
				break;
			}
		}
		if( find_flag == 1 ){
			if( (peri_clk % soft_counter) != 0 ){
				Ddim_Print(("Dd_PMC_TMR32_Calculate:It cannot be divided.\n"));
			}
			break;
		}
	}
	while( 1 ){
		if( find_flag == 1 ){
			for( dividing_wk_1 = dividing[div_wk]; dividing_wk_1 >= 1; dividing_wk_1 /= 2 ){
				if( (peri_clk_wk % dividing_wk_1) == 0 ){
					peri_cnt_1 = (peri_clk_wk / dividing_wk_1);
					break;
				}
			}
			dividing_wk_2 = dividing[div_wk] / dividing_wk_1;
			dividing_wk_3 = dividing_wk_2;

			for( ; dividing_wk_2 >= 1; dividing_wk_2 /= 2 ){
				if( (usec % dividing_wk_2) == 0 ){
					peri_cnt_2 = (usec / dividing_wk_2);
					break;
				}
			}
			dividing_wk_3 = (dividing[div_wk] / dividing_wk_1) / dividing_wk_2;

			for( margin_1 = 1000000; margin_1 > 0; margin_1 /= 10 ){
				if( (peri_cnt_1 % margin_1) == 0 ){
					peri_cnt_1 = (peri_cnt_1 / margin_1);
					break;
				}
			}
			// Division in multiples of 10
			if( (1000000 / margin_1) > 1 ){
				for( margin_2 = (1000000 / margin_1); margin_2 > 0; margin_2 /= 10 ){
					if( (peri_cnt_2 % margin_2) == 0 ){
						peri_cnt_2 = (peri_cnt_2 / margin_2);
						break;
					}
				}
				margin_3 = (1000000 / margin_1) / margin_2;
				peri_cnt_3 = margin_3;
			}
			else{
				margin_2 = 1;
				margin_3 = 1;
				peri_cnt_3 = margin_3;
			}
			// Check overflow
			ret = dd_pmc_tmr32_check_overflow( peri_cnt_1, peri_cnt_2 );
			if( ret != 0 ){
				// Division in multiples of 2
				switch( margin_3 ){
					case 1000000:
						margin_1 = 64;
						margin_2 = 64;
						break;
					case 100000:
						margin_1 = 32;
						margin_2 = 32;
						break;
					case 10000:
						margin_1 = 16;
						margin_2 = 16;
						break;
					case 1000:
						margin_1 = 8;
						margin_2 = 8;
						break;
					case 100:
						margin_1 = 4;
						margin_2 = 4;
						break;
					case 10:
						margin_1 = 2;
						margin_2 = 2;
						break;
					default:
						find_flag = 0;
						Ddim_Print(("Dd_PMC_TMR32_Calculate:It was not possible to request it though it calculated.\n"));
						break;
				}
				for( ; margin_1 > 0; margin_1 /= 2 ){
					if( (peri_cnt_1 % margin_1) == 0 ){
						peri_cnt_1 = (peri_cnt_1 / margin_1);
						break;
					}
				}
				if( (margin_3 / margin_1) > 1 ){
					for( margin_2 = (margin_2 / margin_1); margin_2 > 0; margin_2 /= 2 ){
						if( (peri_cnt_2 % margin_2) == 0 ){
							peri_cnt_2 = (peri_cnt_2 / margin_2);
							break;
						}
					}
					margin_3 = (margin_3 / margin_1) / margin_2;
					peri_cnt_3 = margin_3;
				}
				else{
					margin_2 = 1;
					margin_3 = 1;
					peri_cnt_3 = margin_3;
				}
				ret = dd_pmc_tmr32_check_overflow( peri_cnt_1, peri_cnt_2 );
				if( ret != 0 ){
					find_flag = 0;
					Ddim_Print(("Dd_PMC_TMR32_Calculate:It was not possible to request it though it calculated.\n"));
					break;
				}
			}
			total_count = ((peri_cnt_1 * peri_cnt_2) / dividing_wk_3) / peri_cnt_3;

			// 32bit counter
			tmr32_ctrl->rlr1         = total_count - 1;
			tmr32_ctrl->rlr2         = total_count - 1;
			tmr32_ctrl->soft_counter = soft_counter;
			tmr32_ctrl->csr.word     = 0x00000018;		// Periodic mode, Interrupt Enable, Reload
			tmr32_ctrl->csr.bit.csl  = div_wk;
		}
		break;
	}
	if( find_flag == 1 ){
		return D_DDIM_OK;
	}
	else{
		return D_DD_PMC_TMR32_INPUT_PARAM_ERR;
	}
}


/**
 * @brief  32bit Reload Timer is started.
 * @return INT32 D_DDIM_OK/D_DD_PMC_TMR32_INPUT_PARAM_ERR
 */
INT32 Dd_PMC_TMR32_Start( VOID )
{
	IO_PMC.TMR.TMCSR.word |= 0x0000000B;
	Dd_ARM_Dsb_Pou();

	return D_DDIM_OK;
}

/**
 * @brief  32bit Reload Timer is Stopped.
 * @return INT32 D_DDIM_OK/D_DD_PMC_TMR32_INPUT_PARAM_ERR
 */
INT32 Dd_PMC_TMR32_Stop( VOID )
{
	IO_PMC.TMR.TMCSR.word &= 0xFFFFFFB8;	// UF=0,CNTE=0,CNTE=0

	// If the interrupt request flag set timing and the clear
	// timing clash, the flag set has priority and the clearing
	// operation is disabled.
	IO_PMC.TMR.TMCSR.word &= 0xFFFFFFB8;
	Dd_ARM_Dsb_Pou();

	return D_DDIM_OK;
}


/**
 * @brief  32bit Reload Timer is paused.
 * @return INT32 D_DDIM_OK/D_DD_PMC_TMR32_INPUT_PARAM_ERR
 */
INT32 Dd_PMC_TMR32_Pause( VOID )
{
	IO_PMC.TMR.TMCSR.word &= 0xFFFFFFBD;
	Dd_ARM_Dsb_Pou();

	return D_DDIM_OK;
}

/**
 * @brief  Get designated 32bit Reload Timer counter value.
 * @param  ULONG* h_count, ULONG* s_count
 * @return INT32 D_DDIM_OK/D_DD_PMC_TMR32_INPUT_PARAM_ERR
 */
INT32 Dd_PMC_TMR32_Get_Counter( ULONG* const h_count, ULONG* const s_count )
{
#ifdef CO_PARAM_CHECK
	if( (h_count == NULL) || (s_count == NULL) ){
		Ddim_Assertion(("Dd_PMC_TMR32_Get_Counter: input param error. [*h_count] or [*s_count] is NULL\n"));
		return D_DD_PMC_TMR32_INPUT_PARAM_ERR;
	}
#endif

	*h_count = IO_PMC.TMR.TMR;
	*s_count = gDD_PMC_TMR32_Soft_Counter;

	return D_DDIM_OK;
}

/**
 * @brief  All the register values of 32bit reload timer are acquired.
 * @param  T_DD_PMC_TMR32_CTRL* tmr32_ctrl
 * @return INT32 D_DDIM_OK/D_DD_PMC_TMR32_INPUT_PARAM_ERR
 */
INT32 Dd_PMC_TMR32_Get_Ctrl( T_DD_PMC_TMR32_CTRL* const tmr32_ctrl )
{
#ifdef CO_PARAM_CHECK
	if (tmr32_ctrl == NULL) {
		Ddim_Assertion(("Dd_PMC_TMR32_Get_Ctrl: input param error. [*tmr32_ctrl] NULL\n"));
		return D_DD_PMC_TMR32_INPUT_PARAM_ERR;
	}
#endif

	// Register value acquisition
	tmr32_ctrl->csr.word		= IO_PMC.TMR.TMCSR.word;
	tmr32_ctrl->soft_counter	= gDD_PMC_TMR32_Soft_Counter;
	tmr32_ctrl->pcallback		= gDD_PMC_TMR32_Callback;

	return D_DDIM_OK;
}

/**
 * @brief  Only the soft count value that wants to repeat in the reload mode is set.
 * @param  ULONG soft_counter
 * @return VOID
 */
INT32 Dd_PMC_TMR32_Set_Softcounter( ULONG soft_counter )
{
	gDD_PMC_TMR32_Soft_Counter = soft_counter;

	return D_DDIM_OK;
}

/**
 * @brief  The soft count value is returned.
 * @return ULONG soft counter
 */
ULONG Dd_PMC_TMR32_Get_Softcounter( VOID )
{
	return gDD_PMC_TMR32_Soft_Counter;
}

/**
 * @brief  The reload_flg is set.
 * @param  UCHAR flg
 * @return INT32 D_DDIM_OK
 */
INT32 Dd_PMC_TMR32_Set_Reload_Flg( UCHAR flg )
{
	gDD_PMC_TMR32_Set_Reload_Flg = flg;

	return D_DDIM_OK;
}

/**
 * @brief  The reload_flg value is returned.
 * @return VOID
 */
INT32 Dd_PMC_TMR32_Get_Reload_Flg( VOID )
{
	return gDD_PMC_TMR32_Set_Reload_Flg;
}

/**
 * @brief  The interruption flag is cleared, and the CallBack function for 32bit Reload Timer is called.
 * @return VOID
 */
VOID Dd_PMC_TMR32_Int_Handler( VOID )
{
	union	io_pmc_tmr_tmcsr	tmcsr;

	tmcsr.word = IO_PMC.TMR.TMCSR.word;

	// The channel of the generated interruption is checked. 
	if( (tmcsr.word & 0x00000006) != 0x00000006 ){
		return;
	}
	IO_PMC.TMR.TMCSR.word &= 0xFFFFFFBB;		// UF bit clear
	Dd_ARM_Dsb_Pou();

	// Soft-Counter check
	if( gDD_PMC_TMR32_Soft_Counter > 1 ){
		gDD_PMC_TMR32_Soft_Counter--;
	}
	else{
		// Reload check
		if( (tmcsr.bit.RELD == 1) && (gDD_PMC_TMR32_Set_Reload_Flg == 1) ){	/* pgr0872 */
			gDD_PMC_TMR32_Soft_Counter = gDD_PMC_TMR32_Soft_Counter_Ini;
		}
		else{
			Dd_PMC_TMR32_Stop();
		}

		// Callback check
		if( gDD_PMC_TMR32_Callback ){
			(*gDD_PMC_TMR32_Callback)();	// Call Back function
		}
	}
}

static UCHAR dd_pmc_tmr32_cal_digit( ULONG value )
{
	ULONG digit_value;
	INT8  digit_num;
	UCHAR digit = 0;

	for( digit_num = 31; digit_num >= 0; digit_num-- ){
		digit_value = (1 << digit_num);
		if( value >= digit_value ){
			digit = (digit_num + 1);
			break;
		}
	}

	return digit;
}

static INT32 dd_pmc_tmr32_check_overflow( ULONG param_1, ULONG param_2 )
{
	INT32 ret;
	UCHAR digit_param_1;
	UCHAR digit_param_2;
	USHORT digit_total;

	digit_param_1 = dd_pmc_tmr32_cal_digit( param_1 );
	digit_param_2 = dd_pmc_tmr32_cal_digit( param_2 );

	digit_total = digit_param_1 + digit_param_2;

	if( digit_total <= 32 ){
		ret = 0;
	}
	else{
		ret = 1;
	}

	return ret;
}

static INT32 dd_pmc_tmr32_get_soft_counter( ULONG clk, ULONG time, ULONG dividing, ULONG* soft_counter )
{
	ULONG cnt;
	ULONG cnt_ini;
	ULONG clk_wk;
	INT32 digit_total;
	UCHAR digit_clk;
	UCHAR digit_time;
	UCHAR digit_div;
	UCHAR digit_usec = 20;
	UCHAR err_flg = 0;

	cnt = *soft_counter;
	clk_wk  = clk;
	cnt_ini = *soft_counter;

	for( ;; ){
		digit_clk  = dd_pmc_tmr32_cal_digit( clk_wk );
		digit_time = dd_pmc_tmr32_cal_digit( time );

		if( dividing == 1 ){
			digit_div = 0;
		}
		else{
			digit_div  = dd_pmc_tmr32_cal_digit( dividing );
		}
		digit_total = digit_clk + digit_time - digit_usec - digit_div;

		if( digit_total < 1 ){
			return -1;
		}
		else if( digit_total > 32 ){
			for( cnt = (cnt_ini + 1); ; cnt++ ){
				if( (clk % cnt) == 0 ){
					clk_wk = clk / cnt;
					cnt_ini = cnt;
					break;
				}
				if( clk <= cnt ){
					err_flg = 1;
					break;
				}
			}
			if( err_flg == 1 ){
				*soft_counter = 0;
				Ddim_Print(("dd_pmc_tmr32_get_soft_counter: check overflow error.\n"));
				break;
			}
		}
		else{
			*soft_counter = cnt;
			break;
		}
	}

	return 0;
}

#ifdef CO_DDIM_UTILITY_USE
//---------------------------- utility section ---------------------------
/**
 * @brief  The operation condition of Reload Timer is set.
           Timer value unit:[ms]
 * @param  ULONG usec, ULONG soft_counter, VP_CALLBACK pcallback
 * @return INT32 D_DDIM_OK/D_DD_PMC_TMR32_INPUT_PARAM_ERR
 */
INT32 Dd_PMC_TMR32_SetTimer( ULONG usec, VP_CALLBACK pcallback )
{
	INT32 result;
	T_DD_PMC_TMR32_CTRL tmr32_ctrl;

	// A reload counter and the final, set value are cleared
	gDD_PMC_TMR32_Soft_Counter		= 0;
	gDD_PMC_TMR32_Soft_Counter_Ini	= 0;

	result = Dd_PMC_TMR32_Calculate( usec, &tmr32_ctrl );	// The register count value and the number of repetitions are requested.
	if( result != D_DDIM_OK ){
		Ddim_Print(("Dd_PMC_TMR32_SetTimer: Calculate error. ret=0x%x\n", result));
		return result;
	}
	tmr32_ctrl.pcallback = pcallback;

	//OUTL resetting
	tmr32_ctrl.csr.bit.outl = gDD_PMC_TMR32_Out_Level;

	result = Dd_PMC_TMR32_Ctrl( &tmr32_ctrl );
	if( result != D_DDIM_OK ){
		Ddim_Print(("Dd_PMC_TMR32_SetTimer: ctrl error. ret=0x%x\n", result));
	}
	return result;
}

/**
 * @brief  32bit Reload Timer is started for reload.
 * @return INT32 D_DDIM_OK/D_DD_PMC_TMR32_INPUT_PARAM_ERR
 */
INT32 Dd_PMC_TMR32_StartReload( VOID )
{
	INT32 result = D_DDIM_OK;

	Dd_PMC_TMR32_Set_Reload_Flg( 1 );	// Reload

	IO_PMC.TMR.TMCSR.word |= 0x0000001B;
	Dd_ARM_Dsb_Pou();

	return result;
}

/**
 * @brief  Designated Channel of 32bit Reload Timer is started for oneshot.
 * @return INT32 D_DDIM_OK
 */
INT32 Dd_PMC_TMR32_StartOneshot( VOID )
{
	Dd_PMC_TMR32_Set_Reload_Flg( 0 );		// One shot

	// Reload check
	if( Dd_PMC_TMR32_Get_Softcounter() >= 2 ){
		IO_PMC.TMR.TMCSR.word |= 0x0000001B;
	}
	else{
		IO_PMC.TMR.TMCSR.word &= 0xFFFFFFEF;	// RELD bit clear
		IO_PMC.TMR.TMCSR.word |= 0x0000000B;
	}
	Dd_ARM_Dsb_Pou();

	return D_DDIM_OK;
}

/**
 * @brief  The out_level(OUTL) is set.
 * @param  UINT32 out_level
 * @return INT32 D_DDIM_OK/D_DD_PMC_TMR32_INPUT_PARAM_ERR
 */
INT32 Dd_PMC_TMR32_Set_Outlevel( UINT32 out_level )
{
#ifdef CO_PARAM_CHECK
	if( out_level >= 2 ){
		Ddim_Assertion(("Dd_PMC_TMR32_Set_Outlevel: input param error. [out_level] = %x\n", out_level));
		return D_DD_PMC_TMR32_INPUT_PARAM_ERR;
	}
#endif

	if( out_level == 0 ){
		IO_PMC.TMR.TMCSR.word &= 0xFFFFFFDF;	// OUTL bit clear
	}
	else{
		IO_PMC.TMR.TMCSR.word |= 0x00000020;	// OUTL bit set
	}
	gDD_PMC_TMR32_Out_Level = out_level;

	return D_DDIM_OK;
}

//---------------------------- colabo section ----------------------------
// Nothing Special
#endif
